package cn.chinaunicom.fast.common.exception;

import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartException;

import cn.chinaunicom.fast.common.utils.Result;
import lombok.extern.slf4j.Slf4j;


/**
 *
 * @ProjectName:    common.web
 * @Package:        com.springboot.cloud.common.web.exception
 * @ClassName:      DefaultGlobalExceptionHandlerAdvice
 * @Description:    默认全局异常处理类
 * @Author:         wangjc
 * @CreateDate:     2020/4/14 0014 10:54
 * @UpdateUser:     更新者
 * @UpdateDate:     2020/4/14 0014 10:54
 * @UpdateRemark:   更新内容
 * @Version:        1.0
 */

@Slf4j
public class DefaultGlobalExceptionHandlerAdvice {

    @ExceptionHandler(value = {MissingServletRequestParameterException.class})
    public Result missingServletRequestParameterException(MissingServletRequestParameterException ex) {
        log.error("missing servlet request parameter exception:{}", ex);
        return Result.fail(SystemErrorType.ARGUMENT_NOT_VALID);
    }

    @ExceptionHandler(value = {MultipartException.class})
    public Result uploadFileLimitException(MultipartException ex) {
        log.error("upload file size limit:{}", ex);
        return Result.fail(SystemErrorType.UPLOAD_FILE_SIZE_LIMIT);
    }

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public Result methodException(MethodArgumentNotValidException ex) {
        log.error("method exception :{}", ex);
        return Result.fail(SystemErrorType.ARGUMENT_NOT_VALID, ex.getBindingResult().getFieldError().getDefaultMessage());
    }

    @ExceptionHandler(value = {DuplicateKeyException.class})
    public Result duplicateKeyException(DuplicateKeyException ex) {
        log.error("primary key duplication exception:{}", ex);
        return Result.fail(SystemErrorType.DUPLICATE_PRIMARY_KEY);
    }

    @ExceptionHandler(value = {BaseException.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result baseException(BaseException ex) {
        log.error("base exception:{}", ex);
        return Result.fail(ex.getErrorType());
    }

    @ExceptionHandler(value = {Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result exception(Exception ex) {
        log.error("exception:{}", ex);
        return Result.fail();
    }

    /**
     * 业务异常 - 响应状态码为200
     * @param ex
     * @return
     */
    @ExceptionHandler(value = {ServiceException.class})
    @ResponseStatus(HttpStatus.OK)
    public Result serviceError(ServiceException ex) {
        log.error("service exception:{}", ex);
        return new Result(ex.getCode(), ex.getMsg());
    }

    @ExceptionHandler(value = {Throwable.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result throwable(Throwable throwable) {
        log.error("throwable: {}", throwable);
        return Result.fail();
    }

    @ExceptionHandler(value = {NullPointerException.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result npe(NullPointerException e) {
        log.error("NullPointException: {}", e);
        return Result.fail("NPE");
    }
}